<?php
/**
 * Created by PhpStorm.
 * User: Keter
 * Date: 2016/8/12
 * Time: 18:00
 */
class MysqlDB extends DatabaseBase
{
    private $_driver;

    public function __construct($config)
    {
        $this->_driver = new MysqlDriver();
        if (!$this->_driver->connect($config)) {
            $this->returnError('error_db_connect');
        }
    }

    /**
     * 查询
     * @param $sql
     * @param int $resultmode
     * @return mixed
     */
    public function query($sql, $debug = false, $resultmode = MYSQLI_STORE_RESULT)
    {
        if ($debug) {
            $this->i('sql', $sql);
        }

        $this->_recordSet = $this->_driver->query($sql);
        return $this->_recordSet;
    }

    /**
     * 插入数据
     * @param $table
     * @param array $data
     * @return mixed
     */
    public function insert($table, array $data = array(), $debug = false)
    {
        $table  = $this->real_escape_string($table);
        $sql    = "INSERT INTO %s(%s) VALUES(%s)";
        $fields = $values = '';

        foreach ($data as $field => $value) {
            $field = $this->real_escape_string($field);
            $value = $this->real_escape_string($value);
            $fields = $fields . ',' . $field;
            $values = $values . ", '" . $value . "'";
        }

        $fields = trim($fields, ',');
        $values = trim($values, ',');
        $sql = sprintf($sql, $table, $fields, $values);

        return $this->query($sql, $debug);
    }

    /**
     * 更新数据
     * @param $table
     * @param array $data
     * @param array $where
     * @return mixed
     */
    public function update($table, array $data = array(), $where = array(), $debug = false)
    {
        $table = $this->real_escape_string($table);
        $sql   = "UPDATE %s SET %s %s";
        $set   = $cond = array();

        foreach ($data as $field => $value) {
            $set[] = "{$field} = '{$value}'";
        }

        $set = implode(',', $set);
        if (is_array($where)) {
            foreach ($where as $field => $value) {
                $field = $this->real_escape_string($field);
                $value = $this->real_escape_string($value);
                $cond[] = "{$field} = '{$value}'";
            }
            $cond = implode(' AND ', $cond);
        } else {
            $cond = $where;
        }

        if ($cond) {
            $cond = ' WHERE ' . $cond;
        }

        $sql  = sprintf($sql, $table, $set, $cond);
        return $this->query($sql, $debug);
    }

    /**
     * 查询
     * @param $table
     * @param array $where
     * @param array $option
     * @return array
     */
    public function find($table, $where = array(), $option = '*', $debug = false)
    {
        return $this->_selectQuery($table, $where, $option, $debug);
    }

    /**
     * 查询一行
     * @param $table
     * @param array $where
     * @param array $option
     * @return array
     */
    public function findRow($table, $where = array(), $option = '*', $debug = false)
    {
        return $this->_selectQuery($table, $where, $option, true, $debug);
    }

    /**
     * 生成查询SQL
     * @param $table
     * @param array $where
     * @param array $option
     * @param bool $findRow
     * @return string
     */
    public function _selectQuery($table, $where = array(), $option = '*', $findRow = false, $debug = false)
    {
        $sql = "SELECT %s FROM %s%s%s";
        $table = $this->real_escape_string($table);
        $tail = $fields = '';

        if (is_array($option)) {
            if (isset($option['fields'])) {
                $fields = $option['fields'];
            } else {
                $fields = '*';
            }
        } else {
            $fields = $option;
        }

        if (isset($option['group'])) {
            $tail .= " GROUP BY " . $option['group'];
        }
        if (isset($option['order'])) {
            $tail .= " ORDER BY " . $option['order'];
        }

        if ($findRow) {
            $tail .= " limit 1";
        } elseif (isset($option['limit'])) {
            $tail .= " limit " . $option['limit'];
        }

        if (is_array($where)) {
            $cond = array();
            foreach ($where as $field => $value) {
                $field = $this->real_escape_string($field);
                $value = $this->real_escape_string($value);
                $cond[] = "{$field} = '{$value}'";
            }
            $where = implode(' AND ', $cond);
        }

        if ($where) {
            $where = ' WHERE ' . $where;
        }

        $sql = sprintf($sql, $fields, $table, $where, $tail);
        $this->_recordSet = $this->query($sql, $debug);
        if ($this->_recordSet) {
            return $findRow ? $this->fetch_assoc() : $this->fetch_all();
        }

        return array();
    }

    public function errorExists()
    {
        return $this->_driver->error_no();
    }

    /**
     * 判断表是否存在
     * @param $tableName
     * @return mixed
     */
    public function tableExists($tableName)
    {
        $result = $this->findRow(
            'information_schema.TABLES',
            ['TABLE_SCHEMA' => $this->_driver->name, 'TABLE_NAME' => $tableName],
            'TABLE_NAME'
        );
        return $result;
    }

    /**
     * 选择数据库
     * @param $name
     * @return mixed
     */
    public function selectDB($name)
    {
        return $this->_driver->select_db($name);
    }

    /**
     * 未知方法调用的处理
     * @param string $name
     * @param array $params
     */
    public function __call($name, $params)
    {
        if ($this->_driver && method_exists($this->_driver, $name)) {
            return call_user_func_array(array($this->_driver, $name), $params);
        }

        $this->returnError('no_method');
    }
}